/***************************************************************************************************
 Replication do-file (LAC) — Corruption and Life Satisfaction (AmericasBarometer 2014 / LAPOP)

 Paper: "It’s Not Just the Economy, Stupid: Corruption and Subjective Well Being in Africa,
        and Latin America and the Caribbean"

 Purpose:
   (1) Load LAPOP 2014 dataset
   (2) Construct individual bribery measures (general + specific services)
   (3) Aggregate bribery exposure to the provincial level (prov)
   (4) Recode life satisfaction outcome (ordered)
   (5) Construct controls
   (6) Estimate ordered probit models with clustered SEs and export tables

***************************************************************************************************/

clear
* Load AmericasBarometer / LAPOP 2014 data (dataset must be in Stata path or working directory)
use lapop2014


/***************************************************************************************************
 1) Sample restriction and clustering variable
***************************************************************************************************/

***** generate country/regional incidence of bribery

* Keep subset of countries (pais < 30) as in original analysis
keep if pais < 30
display _N

* Cluster standard errors at the country × province level
egen clustervar = group(pais prov)


/***************************************************************************************************
 2) Bribery measures (individual level)
    Missing value handling:
      - LAPOP extended missing codes (.a .b .c .z) are recoded to Stata missing (.)
***************************************************************************************************/

* General question (can overlap with specific types): bureaucratic bribe
gen burobribe = exc6
replace burobribe = . if burobribe == .a
replace burobribe = . if burobribe == .b
replace burobribe = . if burobribe == .c
replace burobribe = . if burobribe == .z

* Specific types of corruption/bribery:

* Police bribe
generate bribepolice = exc2
replace bribepolice = . if bribepolice == .a
replace bribepolice = . if bribepolice == .b
replace bribepolice = . if bribepolice == .c
replace bribepolice = . if bribepolice == .z

* Soldier/military bribe
gen soldierbribe = exc20
replace soldierbribe = . if soldierbribe == .a
replace soldierbribe = . if soldierbribe == .b
replace soldierbribe = . if soldierbribe == .c
replace soldierbribe = . if soldierbribe == .z

* Documents/permits bribe
gen docbribe = exc11
replace docbribe = . if docbribe == .a
replace docbribe = . if docbribe == .b
replace docbribe = . if docbribe == .c
replace docbribe = . if docbribe == .z
* Country-specific substitution for pais==28 or pais==29 (alternative variable)
replace docbribe = bahexc11 if pais == 28 | pais == 29

* Court/judicial bribe
gen courtbribe = exc14
replace courtbribe = . if courtbribe == .a
replace courtbribe = . if courtbribe == .b
replace courtbribe = . if courtbribe == .c
replace courtbribe = . if courtbribe == .z

* Medical bribe
gen medicalbribe = exc15
replace medicalbribe = . if medicalbribe == .a
replace medicalbribe = . if medicalbribe == .b
replace medicalbribe = . if medicalbribe == .c
replace medicalbribe = . if medicalbribe == .z

* School bribe
gen schoolbribe = exc16
replace schoolbribe = . if schoolbribe == .a
replace schoolbribe = . if schoolbribe == .b
replace schoolbribe = . if schoolbribe == .c
replace schoolbribe = . if schoolbribe == .z


/*** 2.1) Total bribery exposure ***/
* Row-wise total across bribery contexts (counts non-missing components)
egen bribetotal = rowtotal(burobribe bribepolice soldierbribe docbribe courtbribe medicalbribe schoolbribe)

* Dummy: any bribery experience
gen bribetotaldum = 0
replace bribetotaldum = 1 if bribetotal > 0
replace bribetotaldum = . if bribetotal == .


/***************************************************************************************************
 3) Contextual (provincial) bribery measures
***************************************************************************************************/

* Provincial mean of "any bribery" dummy
bysort prov: egen float regbribe = mean(bribetotaldum)

* Provincial means by service context
bysort prov: egen float regbribepolice  = mean(bribepolice)
bysort prov: egen float regschoolbribe  = mean(schoolbribe)
bysort prov: egen float regmedicalbribe = mean(medicalbribe)
bysort prov: egen float regdocbribe     = mean(docbribe)
bysort prov: egen float regsoldierbribe = mean(soldierbribe)
bysort prov: egen float regcourtbribe   = mean(courtbribe)
bysort prov: egen float regburobribe    = mean(burobribe)


/***************************************************************************************************
 4) Dependent variable: life satisfaction
    Original ls3: lower is better, so it is reversed into satisfaction where higher is better.
***************************************************************************************************/

**** DEPENDENT VARIABLE: life satisfaction (lower is better, so recode)
*** Only has four values
tab ls3
tab ls3, nolab

* Reverse coding: 4→1, 3→2, 2→3, 1→4
recode ls3 (4=1) (3=2) (2=3) (1=4), gen(satisfaction)


/***************************************************************************************************
 5) Controls
***************************************************************************************************/

**** CONTROLS

* Gender (female=1, male=0)
gen female = .
replace female = 1 if sex == 2
replace female = 0 if sex == 1

* Urban residence (urban=1, rural=0)
gen urban = .
replace urban = 0 if ur == 2
replace urban = 1 if ur == 1

* Age (and squared term)
rename q2 age
gen ageSQ = age*age

* Income/poverty proxy and provincial mean income
rename q10new income
bysort prov: egen float regincome = mean(income)

* Education (collapsed into five categories)
gen education = .
replace education = 1 if ed <= 5
replace education = 2 if ed <= 11 & ed > 5
replace education = 3 if ed == 12
replace education = 4 if ed <= 16 & ed > 12
replace education = 5 if ed > 16

* Education labels
label define educa ///
  1 "Less than full primary" ///
  2 "Primary or Some Secondary" ///
  3 "Secondary" ///
  4 "Post Secondary Qualification or Some Uni." ///
  5 "Uni. Complete & Postgrad"
label values education educa


/***************************************************************************************************
 6) Descriptive statistics and complete-case restriction
    Variable n counts missingness across the model variables used later.
***************************************************************************************************/

*** Descriptive Stats
gen n = missing(satisfaction) + missing(burobribe) + missing(regburobribe) + ///
        missing(age) + missing(ageSQ) + missing(female) + ///
        missing(education) + missing(income) + missing(regincome) + missing(urban)

* Keep only observations with complete data on key variables
keep if n == 0

* Quick distributions / summaries
tab satisfaction
tab education
sum burobribe regburobribe age female income regincome urban regcourtbribe


/***************************************************************************************************
 7) Results: Bureaucratic corruption (individual + contextual) and marginal effects
***************************************************************************************************/

*** Results for Bureaucratic Corruption
estimates clear

* Ordered probit of satisfaction on individual bureaucratic bribery + provincial bureaucratic bribery
xi: oprobit satisfaction burobribe regburobribe age ageSQ female i.education income regincome urban i.pais, cluster(clustervar)
eststo oprobit

* Compute marginal effects for each outcome category of satisfaction
foreach o in 1 2 3 4 {
  quietly margins, dydx(*) predict(outcome(`o')) post
  eststo, title(Outcome `o')
  estimates restore oprobit
}

* Export marginal effects table
eststo drop oprobit
esttab using "latam_buro_1124.csv", nogaps se star(* 0.10 ** 0.05 *** 0.01) drop(_Ipais_*) ///
  mtitles b(%7.4f) se(%7.5f) sfmt(%7.5f) compress replace


/*** 7.1) Marginal changes at means ***/
xi: oprobit satisfaction burobribe regburobribe age ageSQ female i.education income regincome urban i.pais, cluster(clustervar)

* Marginal change for key predictors at means (centered)
mchange regburobribe burobribe income female, atmeans centered
mchange _Ieducation_5, atmeans stats(ci) centered


/***************************************************************************************************
 8) Which bribery context is “worst” (contextual measures one-by-one + table export)
***************************************************************************************************/

*** what context is worst?
estimates clear

xi: oprobit satisfaction burobribe regbribepolice age ageSQ female i.education income regincome urban i.pais, cluster(clustervar)
eststo oprobit1

xi: oprobit satisfaction burobribe regschoolbribe age ageSQ female i.education income regincome urban i.pais, cluster(clustervar)
eststo oprobit2

xi: oprobit satisfaction burobribe regmedicalbribe age ageSQ female i.education income regincome urban i.pais, cluster(clustervar)
eststo oprobit3

xi: oprobit satisfaction burobribe regdocbribe age ageSQ female i.education income regincome urban i.pais, cluster(clustervar)
eststo oprobit4

xi: oprobit satisfaction burobribe regsoldierbribe age ageSQ female i.education income regincome urban i.pais, cluster(clustervar)
eststo oprobit5

xi: oprobit satisfaction burobribe regcourtbribe age ageSQ female i.education income regincome urban i.pais, cluster(clustervar)
eststo oprobit6

* Export table comparing models across contexts
esttab using "latam_context_1124.csv", nogaps se star(* 0.10 ** 0.05 *** 0.01) drop(_Ipais_*) ///
  mtitles b(%7.4f) se(%7.5f) sfmt(%7.5f) compress replace


/***************************************************************************************************
 9) Context models by gender (women vs. men), table export
***************************************************************************************************/

estimates clear

* Women only (female==1)
xi: oprobit satisfaction burobribe regbribepolice age ageSQ i.education income regincome urban i.pais, cluster(clustervar), if female == 1
eststo oprobit1
xi: oprobit satisfaction burobribe regschoolbribe age ageSQ i.education income regincome urban i.pais, cluster(clustervar), if female == 1
eststo oprobit2
xi: oprobit satisfaction burobribe regmedicalbribe age ageSQ i.education income regincome urban i.pais, cluster(clustervar), if female == 1
eststo oprobit3
xi: oprobit satisfaction burobribe regdocbribe age ageSQ i.education income regincome urban i.pais, cluster(clustervar), if female == 1
eststo oprobit4
xi: oprobit satisfaction burobribe regsoldierbribe age ageSQ i.education income regincome urban i.pais, cluster(clustervar), if female == 1
eststo oprobit5
xi: oprobit satisfaction burobribe regcourtbribe age ageSQ i.education income regincome urban i.pais, cluster(clustervar), if female == 1
eststo oprobit6

* Men only (female==0)
xi: oprobit satisfaction burobribe regbribepolice age ageSQ i.education income regincome urban i.pais, cluster(clustervar), if female == 0
eststo oprobit7
xi: oprobit satisfaction burobribe regschoolbribe age ageSQ i.education income regincome urban i.pais, cluster(clustervar), if female == 0
eststo oprobit8
xi: oprobit satisfaction burobribe regmedicalbribe age ageSQ i.education income regincome urban i.pais, cluster(clustervar), if female == 0
eststo oprobit9
xi: oprobit satisfaction burobribe regdocbribe age ageSQ i.education income regincome urban i.pais, cluster(clustervar), if female == 0
eststo oprobit10
xi: oprobit satisfaction burobribe regsoldierbribe age ageSQ i.education income regincome urban i.pais, cluster(clustervar), if female == 0
eststo oprobit11
xi: oprobit satisfaction burobribe regcourtbribe age ageSQ i.education income regincome urban i.pais, cluster(clustervar), if female == 0
eststo oprobit12

* Export gender-specific context model table
esttab using "latam_context_gender.csv", nogaps se star(* 0.10 ** 0.05 *** 0.01) drop(_Ipais_*) ///
  mtitles b(%7.3f) se(%7.3f) sfmt(%7.3f) compress replace


/***************************************************************************************************
 10) Judicial corruption: marginal changes for full sample and by gender
***************************************************************************************************/

** Judicial Corruption Marginal Effects

* Full sample
xi: oprobit satisfaction burobribe regcourtbribe age ageSQ female i.education income regincome urban i.pais, cluster(clustervar)
eststo oprobit
mchange regcourtbribe, atmeans centered

* Women
xi: oprobit satisfaction burobribe regcourtbribe age ageSQ i.education income regincome urban i.pais, cluster(clustervar), if female == 1
mchange regcourtbribe, atmeans centered

* Men
xi: oprobit satisfaction burobribe regcourtbribe age ageSQ i.education income regincome urban i.pais, cluster(clustervar), if female == 0
mchange regcourtbribe, atmeans centered


/***************************************************************************************************
 11) All contexts together (single model), marginal effects per outcome, table export
***************************************************************************************************/

** All contexts together
estimates clear

xi: oprobit satisfaction burobribe regbribepolice regschoolbribe regmedicalbribe regdocbribe regsoldierbribe regcourtbribe ///
  age ageSQ female i.education income regincome urban i.pais, cluster(clustervar)
eststo oprobit

* Compute marginal effects for each outcome category
foreach o in 1 2 3 4 {
  quietly margins, dydx(*) predict(outcome(`o')) post
  eststo, title(Outcome `o')
  estimates restore oprobit
}

* Export marginal effects table
eststo drop oprobit
esttab using "latam_contextAll_1124.csv", nogaps se star(* 0.10 ** 0.05 *** 0.01) drop(_Ipais_*) ///
  mtitles b(%7.4f) se(%7.5f) sfmt(%7.5f) compress replace


/***************************************************************************************************
 12) All-context model by gender (women vs. men), marginal effects per outcome, table export
***************************************************************************************************/

*** are different contexts worse for men vs women?
estimates clear

* Women only
xi: oprobit satisfaction burobribe regbribepolice regschoolbribe regmedicalbribe regdocbribe regsoldierbribe regcourtbribe ///
  age ageSQ i.education income regincome urban i.pais, cluster(clustervar), if female == 1
eststo oprobit

foreach o in 1 2 3 4 {
  quietly margins, dydx(*) predict(outcome(`o')) post
  eststo, title(Outcome `o')
  estimates restore oprobit
}

eststo drop oprobit
esttab using "latam_contextfemale.csv", nogaps se star(* 0.10 ** 0.05 *** 0.01) ///
  drop(_Ipais_* age ageSQ _Ieducation_* income regincome urban) mtitles b(%7.4f) se(%7.5f) sfmt(%7.5f) ///
  compress replace

* Men only
estimates clear

xi: oprobit satisfaction burobribe regbribepolice regschoolbribe regmedicalbribe regdocbribe regsoldierbribe regcourtbribe ///
  age ageSQ i.education income regincome urban i.pais, cluster(clustervar), if female == 0
eststo oprobit

foreach o in 1 2 3 4 {
  quietly margins, dydx(*) predict(outcome(`o')) post
  eststo, title(Outcome `o')
  estimates restore oprobit
}

eststo drop oprobit
esttab using "latam_contextmale.csv", nogaps se star(* 0.10 ** 0.05 *** 0.01) ///
  drop(_Ipais_* age ageSQ _Ieducation_* income regincome urban) mtitles b(%7.4f) se(%7.5f) sfmt(%7.5f) ///
  compress replace
